# Author: Damian 'Rush' Kaczmarek
# License: MIT

# TODO:
# -Sanitize values at get() and set()
# -Ease getting hash elements and array elements
# -Allow different order of sections?

package Config;

my %config;    # Config will be basically hashes of hashes

# Lead the config file
open(CONFIG, $Core::configfile);
my $section;
while (<CONFIG>) {

	# [word] -- it is a section
	if (m/^\[(.*)\]/) {
		$section = $1;
	}

	# word[number]=definition -- it is an array!
	elsif (m/(\w+)\[(\d+)\]=(.*)/ && defined($section)) {
		$config{$section}{$1}[$2] = $3;
	}

	# word[word]=definition -- it is an associative array!
	elsif (m/(\w+)\[(\w+)\]=(.*)/ && defined($section)) {
		$config{$section}{$1}{$2} = $3;
	}

	# word=definition -- it is an ordinary string
	elsif (m/(\w+)=(.*)/ && defined($section)) {
		$config{$section}{$1} = $2;
	}
}

close(CONFIG);
return 1;    # Return true value to satifly perl loader

# Get arbitrary variable
# $_[0] - variable name
# $_[1] - default value to return in case the variable was not found
# $_[2] - default value to return in case the variable was not found
sub get_from
{
	my ($package, $variable, $default) = @_;

	$value = $config{$package}{$variable};
	if ($value ne "") {
		if (ref($config{$section}{$variable}) eq "HASH") {
			return %{$value};
		}
		elsif (ref($config{$section}{$variable}) eq "ARRAY") {
			return @{$value};
		}
		else {
			return $value;
		}
	}
	set($package, $variable, $default);    # Set on read
	return $default;
}

# Get arbitrary variable
# $_[0] - variable name
# $_[1] - default value to return in case the variable was not found
sub get
{
	my ($variable, $default) = @_;

	my $package = caller();
	return get_from($package, $variable, $default);
}

# Set arbitrary variable
# $_[0] - package name
# $_[1] - variable name
# $_[2] - value to set
sub set
{
	(my $package, my $variable, my $value) = @_;

	# Remove the package location from the name to increase readability
	$package =~ s/^.*:://;

	$config{$package}{$variable} = $value;
}

# Saves config to a config file
sub save
{
	open(CONFIG, ">" . $Core::configfile);
	foreach $section (keys(%config)) {
		print CONFIG "\n[$section]\n";
		foreach $variable (keys(%{$config{$section}})) {

			# Variable is a hash
			if (ref($config{$section}{$variable}) eq "HASH") {
				foreach my $key (keys(%{$config{$section}{$variable}})) {
					print CONFIG $variable . "[$key]=" . $config{$section}{$variable}{$key} . "\n";
				}

			}

			# Variable is an array
			elsif (ref($config{$section}{$variable}) eq "ARRAY") {
				my $i = 0;
				foreach my $elem (@{$config{$section}{$variable}}) {
					print CONFIG "$variable" . "[" . $i++ . "]=$elem\n";
				}
			}

			# Ordinary variable
			else {
				print CONFIG "$variable=" . $config{$section}{$variable} . "\n";
			}
		}
	}
	close(CONFIG);
}
